﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows;
using System.Windows.Forms;
using ContextMenu = System.Windows.Controls.ContextMenu;

namespace Foundation
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public class TrayWindowView : WindowView
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="TrayWindowView"/> class.
        /// </summary>
        public TrayWindowView()
        {
            PropertyChanged += (sender, args) => { };
        }

        public static readonly DependencyProperty VisibileProperty = DependencyProperty.Register(
            "Visibile",
            typeof(Boolean),
            typeof(TrayWindowView),
            new FrameworkPropertyMetadata(false, DependencyPropertyChanged));

        public static readonly new DependencyProperty IconProperty = DependencyProperty.Register(
            "Icon", typeof(Icon), typeof(TrayWindowView), new FrameworkPropertyMetadata(DependencyPropertyChanged));

        public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
            "Text", typeof(string), typeof(TrayWindowView), new FrameworkPropertyMetadata());

        public static readonly new DependencyProperty ContextMenuProperty = DependencyProperty.Register(
            "ContextMenu", typeof(ContextMenu), typeof(TrayWindowView), new FrameworkPropertyMetadata(DependencyPropertyChanged));

        private readonly NotifyIcon _notifyIcon = new NotifyIcon();

        /// <summary>
        /// Gets the notify icon.
        /// </summary>
        public NotifyIcon NotifyIcon
        {
            get { return _notifyIcon; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="TrayWindowView"/> is visibile.
        /// </summary>
        /// <value>
        ///   <c>true</c> if visibile; otherwise, <c>false</c>.
        /// </value>
        public bool Visibile
        {
            get { return (bool) GetValue(VisibileProperty); }
            set { SetValue(VisibileProperty, value); }
        }

        /// <summary>
        /// Gets or sets a window's icon.
        /// </summary>
        /// <returns>An <see cref="T:System.Windows.Media.ImageSource"/> object that represents the icon.</returns>
        public new Icon Icon
        {
            get { return (Icon) GetValue(IconProperty); }
            set { SetValue(IconProperty, value); }
        }

        /// <summary>
        /// Gets or sets the text.
        /// </summary>
        /// <value>
        /// The text.
        /// </value>
        public string Text
        {
            get { return (string) GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        /// <summary>
        /// Gets or sets the context menu element that should appear whenever the context menu is requested through user interface (UI) from within this element.
        /// </summary>
        /// <returns>The context menu assigned to this element. </returns>
        public new ContextMenu ContextMenu
        {
            get { return (ContextMenu) GetValue(ContextMenuProperty); }
            set { SetValue(ContextMenuProperty, value); }
        }

        /// <summary>
        /// Occurs when [property changed].
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        private static void DependencyPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs args)
        {
            var @this = (TrayWindowView)o;

            switch (args.Property.Name)
            {
                case "Icon":
                    @this._notifyIcon.Icon = (Icon)args.NewValue;
                    break;
                case "Text":
                    @this._notifyIcon.Text = (string)args.NewValue;
                    break;
                case "Visibile":
                    @this._notifyIcon.Visible = (bool)args.NewValue;
                    break;
            }
            @this.PropertyChanged(@this, new PropertyChangedEventArgs(args.Property.Name));
        }
    }
}
